bitkeeper revision 1.1159.17.18 (411b7a4clSlwGNpVa4jPTa9wgDjfmw)
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Thu, 12 Aug 2004 14:10:20 +0000 (14:10 +0000)
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Thu, 12 Aug 2004 14:10:20 +0000 (14:10 +0000)
Add compile-time option to use writable pagetables.

linux-2.6.7-xen-sparse/arch/xen/Kconfig
linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c
linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/page.h
linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgalloc.h
linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h

index c1eb03cda17327be6cd2f6156116663f761355d6..72733f2efc0e72fedc77bc90cccc7f13a5b5952f 100644 (file)
@@ -36,6 +36,12 @@ config XEN_PHYSDEV_ACCESS
        help
          Device-driver domain (physical device access)
 
+config XEN_WRITABLE_PAGETABLES
+       bool "Use writable pagetables"
+       default n
+       help
+         Use writable L1 pagetables
+
 endmenu
 
 # Xen's block device backend driver needs 2^12 pages
index 64cf45c49d8144296ec680c2c299afa86867d6be..c45654a89ea4b976a6d0cc7b2c746c220b8717da 100644 (file)
@@ -1104,7 +1104,7 @@ void __init setup_arch(char **cmdline_p)
 
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_4gb_segments);
-#if 0
+#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_writeable_pagetables);
 #endif
index 17aceff54171932e1f8240b87e9bacbb94698eeb..c7999f04bd763fd0163736af650b34268d2a7614 100644 (file)
@@ -95,7 +95,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 static inline unsigned long pmd_val(pmd_t x)
 {
     unsigned long ret = x.pmd;
-    if ( (ret & 1) ) ret = machine_to_phys(ret);
+    if ( (ret) ) ret = machine_to_phys(ret);
     return ret;
 }
 #define pgd_val(x)     ({ BUG(); (unsigned long)0; })
index c9cc3446790999ae1582db8a01722f945b4128fb..ea933dd2ee239688db221bc0bc13c5c21f543459 100644 (file)
@@ -6,6 +6,7 @@
 #include <asm/fixmap.h>
 #include <linux/threads.h>
 #include <linux/mm.h>          /* for struct page */
+#include <asm/io.h>            /* for phys_to_virt and page_to_pseudophys */
 
 #define pmd_populate_kernel(mm, pmd, pte) \
                set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
@@ -15,7 +16,8 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *p
        set_pmd(pmd, __pmd(_PAGE_TABLE +
                ((unsigned long long)page_to_pfn(pte) <<
                        (unsigned long long) PAGE_SHIFT)));
-       flush_page_update_queue(); /* XXXcl flush */
+       flush_page_update_queue();
+       /* XXXcl queue */
 }
 /*
  * Allocate and free page tables.
@@ -30,17 +32,25 @@ extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
 static inline void pte_free_kernel(pte_t *pte)
 {
        free_page((unsigned long)pte);
+       __make_page_writeable(pte);
 }
 
 static inline void pte_free(struct page *pte)
 {
-       __free_page(pte);
+#ifdef CONFIG_HIGHPTE
+       if (pte < highmem_start_page)
+#endif
+       {
+               __make_page_writeable(phys_to_virt(page_to_pseudophys(pte)));
+               __free_page(pte);
+       }
 }
 
 
 #define __pte_free_tlb(tlb,pte) do {                   \
        tlb_remove_page((tlb),(pte));                   \
-       flush_page_update_queue(); /* XXXcl flush */    \
+       flush_page_update_queue();                      \
+       /* XXXcl queue */ \
 } while (0)
 
 /*
index 58e51fc2bd6c12d9e30f74b4d455422354a72c83..760569f95da0170c4197d78aa49984f6fd182ff7 100644 (file)
@@ -40,8 +40,13 @@ static inline int pgd_present(pgd_t pgd)     { return 1; }
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
+#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval)
+#else
 #define set_pte(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low)
 #define set_pte_atomic(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low)
+#endif
 /*
  * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
@@ -70,7 +75,7 @@ static inline pte_t ptep_get_and_clear(pte_t *xp)
 {
        pte_t pte = *xp;
        if (pte.pte_low)
-               queue_l1_entry_update(xp, 0);
+               set_pte(xp, __pte_ma(0));
        return pte;
 }
 
index 9026d626420c108ab637de69f1bf2c99af07c826..ae068a12b2bdbfe1e8f10eebccf4224d9fa4eb8f 100644 (file)
@@ -191,7 +191,7 @@ extern unsigned long pg0[];
 #define pmd_none(x)    (!pmd_val(x))
 #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
 /* pmd_clear below */
-#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
 
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
@@ -241,9 +241,9 @@ static inline  int ptep_test_and_clear_young(pte_t *ptep)
 }
 static inline void ptep_set_wrprotect(pte_t *ptep)
 {
-       unsigned long pteval = *(unsigned long *)ptep;
-       if ((pteval & _PAGE_RW))
-               queue_l1_entry_update(ptep, pteval & ~_PAGE_RW);
+       pte_t pte = *ptep;
+       if (pte_write(pte))
+               set_pte(ptep, pte_wrprotect(pte));
 }
 static inline void ptep_mkdirty(pte_t *ptep)
 {
@@ -283,6 +283,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
        pmd_t p = *(xp);                                        \
        set_pmd(xp, __pmd(0));                                  \
        __make_page_writeable((void *)pmd_page_kernel(p));      \
+       /* XXXcl queue */ \
 } while (0)
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -401,6 +402,7 @@ static inline void make_page_readonly(void *va)
        if ( (unsigned long)va >= VMALLOC_START )
                __make_page_readonly(machine_to_virt(
                        *(unsigned long *)pte&PAGE_MASK));
+       /* XXXcl queue */
 }
 
 static inline void make_page_writeable(void *va)
@@ -412,6 +414,7 @@ static inline void make_page_writeable(void *va)
        if ( (unsigned long)va >= VMALLOC_START )
                __make_page_writeable(machine_to_virt(
                        *(unsigned long *)pte&PAGE_MASK));
+       /* XXXcl queue */
 }
 
 static inline void make_pages_readonly(void *va, unsigned int nr)
@@ -421,6 +424,7 @@ static inline void make_pages_readonly(void *va, unsigned int nr)
                make_page_readonly(va);
                va = (void *)((unsigned long)va + PAGE_SIZE);
        }
+       /* XXXcl queue */
 }
 
 static inline void make_pages_writeable(void *va, unsigned int nr)
@@ -430,6 +434,7 @@ static inline void make_pages_writeable(void *va, unsigned int nr)
                make_page_writeable(va);
                va = (void *)((unsigned long)va + PAGE_SIZE);
        }
+       /* XXXcl queue */
 }
 
 static inline unsigned long arbitrary_virt_to_phys(void *va)